package com.booter.webflux.http.factory;

import com.booter.webflux.http.annotation.ServiceApi;
import com.booter.webflux.http.processor.CreateProcessor;
import org.apache.commons.lang3.StringUtils;
import org.reflections.Reflections;
import org.reflections.scanners.TypeAnnotationsScanner;
import org.reflections.util.ConfigurationBuilder;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor;
import org.springframework.beans.factory.support.GenericBeanDefinition;
import org.springframework.beans.factory.support.RootBeanDefinition;

import java.util.Set;

/**
 * 会有如下提示
 * Cannot enhance @Configuration bean definition 'serviceConfig' since its singleton instance has been created too early.
 * The typical cause is a non-static @Bean method with a BeanDefinitionRegistryPostProcessor return type: Consider declaring such methods as 'static'.
 */
@Deprecated
public class HttpBeanDefinitionRegistryPostProcessor implements BeanDefinitionRegistryPostProcessor {

    private String packageName;
    private CreateProcessor processor;

    public HttpBeanDefinitionRegistryPostProcessor() {
    }

    public HttpBeanDefinitionRegistryPostProcessor(String packageName) {
        this.packageName = packageName;
    }

    @Override
    public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
//        BeanDefinitionBuilder beanDefinitionBuilder = BeanDefinitionBuilder.genericBeanDefinition(HttpFactoryBean.class);
//        AbstractBeanDefinition beanDefinition = beanDefinitionBuilder.getBeanDefinition();
//        beanDefinition.getConstructorArgumentValues().addGenericArgumentValue("com.tjx.mapper.TestMapper");
//        beanDefinitionRegistry.registerBeanDefinition("mapper", beanDefinition);

        Reflections reflections = new Reflections(new ConfigurationBuilder().forPackages(packageName).addScanners(new TypeAnnotationsScanner()));
        Set<Class<?>> set = reflections.getTypesAnnotatedWith(ServiceApi.class);
        set.forEach(s -> {
            RootBeanDefinition definition = new RootBeanDefinition();
            definition.setBeanClass(HttpFactoryBean.class);
            definition.setLazyInit(true);
            definition.getConstructorArgumentValues().addGenericArgumentValue(s);
            definition.setAutowireMode(GenericBeanDefinition.AUTOWIRE_BY_TYPE);
            definition.setAttribute("processor", processor);
            String name = StringUtils.uncapitalize(s.getSimpleName());
            registry.registerBeanDefinition(name, definition);
        });

    }

    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
        // do nothing

    }

    public void setProcessor(CreateProcessor processor) {
        this.processor = processor;
    }
}
